package slevnik.Web;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import slevnik.*;

/**
 * MainServlet handles the HTTP request for root web page.
 *
 * @author Vit Hovezak
 */
public class MainServlet extends HttpServlet {

    @Resource(name="jdbc/slevnik")
    private DataSource ds;

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        String path = request.getServletPath();

        if (path.equals("/") || path.equals("/index.jsp")) {
            mainPage(request, response);
        }
        else {
            throw new RuntimeException("Unknown operation: " + request.getServletPath());
        }
    }

    /*
     * Processes requests for main page with parameters in URL.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    private void mainPage(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        List<Category> categories = null;
        List<Item> items = null;
        int itemsCount = 0;
        int pagesCount = 0;

        String city = null;
        int categoryId = 0;
        String sortBy = "id";
        int page = 0;
        Boolean sortAsc = Boolean.TRUE;
        String find = null;
        String nearest = null;

        String cityParam = request.getParameter("city");
        String categoryParam = request.getParameter("category");
        String sortParam = request.getParameter("sort");
        String ascParam = request.getParameter("asc");
        String pageParam = request.getParameter("page");
        String findParam = request.getParameter("find");
        String nearestParam = request.getParameter("nearest");

        if (cityParam != null && !cityParam.equals("")) {
            city = cityParam;
        }
        if (categoryParam != null && !categoryParam.equals("")) {
            categoryId = Integer.parseInt(categoryParam);
            if (categoryId < 0) {
                categoryId = 0;
            }
        }
        if (sortParam != null && !sortParam.equals("")) {
            if (sortParam.equals("price")) {
                sortBy = "final_price";
            }
            else if (sortParam.equals("time")) {
                sortBy = "dealend";
            }
            else if (sortParam.equals("customers")) {
                sortBy = "customers";
            }
        }
        if (ascParam != null && !ascParam.equals("")) {
            if (ascParam.equals("false")) {
                sortAsc = Boolean.FALSE;
            }
        }
        if (pageParam != null && !pageParam.equals("")) {
            page = Integer.parseInt(pageParam);
            if (page < 0) {
                page = 0;
            }
        }
        if (findParam != null && !findParam.equals("")) {
            find = findParam;
        }
        if (nearestParam != null && !nearestParam.equals("")) {
            nearest = nearestParam;
        }

        try {
            CategoryManager categoryManager = new CategoryManagerImpl(ds);
            ItemManager itemManager = new ItemManagerImpl(ds);
            ResultManager resultManager = new ResultManagerImpl(ds);

            try {
                categories = categoryManager.findAllCategories();
                request.setAttribute("categories", categories);
                if (find != null) {
                    items = itemManager.findItemsByText(find, sortBy, sortAsc);
                    request.setAttribute("find", find);
                }
                else if (nearest != null) {
                    items = itemManager.findItemsByDistanceToCity(nearest);
                    request.setAttribute("nearest", nearest);
                }
                else if (city != null && categoryId != 0) {
                    Category category = categoryManager.findCategoryById(categoryId);
                    items = resultManager.findItemsByCityAndCategory(city, category, sortBy, sortAsc);
                }
                else if (city != null) {
                    items = itemManager.findItemsByCity(city, sortBy, sortAsc);
                }
                else if (categoryId != 0) {
                    Category category = categoryManager.findCategoryById(categoryId);
                    items = resultManager.findItemsByCategory(category, sortBy, sortAsc);
                }
                else {
                    items = itemManager.findAllItems(sortBy, sortAsc);
                }
                request.setAttribute("items", items);
            } catch (SlevnikException ex) {
                Logger.getLogger(MainServlet.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (SQLException ex) {
            Logger.getLogger(MainServlet.class.getName()).log(Level.SEVERE, null, ex);
        }

        if (items != null) {
            itemsCount = items.size();
            pagesCount = itemsCount / 10;
            if (page > pagesCount) {
                page = 0;
            }
        }
        request.setAttribute("itemsCount", itemsCount);
        request.setAttribute("pagesCount", pagesCount);
        request.setAttribute("page", page);

        request.getRequestDispatcher("main.jsp").forward(request, response);
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "MainServlet processes requests for root web page.";
    }// </editor-fold>
}
